#ifndef HASHING_HPP
#define	HASHING_HPP

#include "sha2/sha2.h"
#include "lex_cast.h"
#include <string>
#include <iostream>
using namespace std;

typedef uint64_t hash_t;

template <typename T>
hash_t get_hash(const T& arg2) {
	int not_used;
	sha2 hasher;
	string arg = ::stringify(arg2); // TODO: Could specialize this template for int,float,string etc, but stringify will work for everything and we are lazy

	hasher.GetHash(sha2::enuSHA256, (const unsigned char *)arg.c_str(), arg.size());
	unsigned char *res = (unsigned char*)hasher.RawHash(not_used);

	// Return only 64 bits from the sha256-hash -- enough for our purposes
	hash_t ret = 0;
	ret = uint(res[0]);
	for (int i = 1; i < 64/8; i++) {
		ret <<= 8;
		ret |= uint(res[i]);
	}
	return ret;
}


#endif	/* HASHING_HPP */
